package com.redstar.HappyRefresh.controller;

import com.redstar.HappyRefresh.constant.RedisConstant;
import com.redstar.HappyRefresh.pojo.*;
import com.redstar.HappyRefresh.service.CaptchaService;
import com.redstar.HappyRefresh.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;

@Slf4j
@RestController
@RequestMapping("/luckyjourney/login")
public class LoginController { // 登录

    @Autowired
    private UserService userService;
    @Autowired
    private CaptchaService captchaService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @PostMapping
    public Result login(@RequestBody @Validated User user) { // 登录
        return Result.succeed().data(userService.login(user));
    }

    @GetMapping("/captcha/{uuid}") // 返回验证码图片
    public void captcha(HttpServletResponse response, @PathVariable String uuid) throws IOException {
        if (!StringUtils.hasLength(uuid)) {
            log.error("captcha方法：uuid为空");
            throw new RuntimeException("uuid为空");
        }
        response.setHeader("Cache-Control", "no-store, no-cache"); // 设置请求头
        response.setContentType("image/jpeg"); // 设置Content-Type头，告诉浏览器或客户端接收的内容类型是JPEG图片格式
        // 通过kaptcha框架生成图片验证码
        BufferedImage image = captchaService.getCaptcha(uuid);
        // 获取用于写入响应体的ServletOutputStream对象
        // ServletOutputStream是一种可以用来输出二进制内容的输出流，通常用于返回图像、PDF文件等非文本内容
        // 使用try-with-resources语句自动管理资源的关闭
        try (ServletOutputStream out = response.getOutputStream()) {
            // 第1个参数是要写入的图像，第2个参数是图像的格式，第3个参数是输出流
            // 将图像数据以JPEG格式写入到HTTP响应中
            ImageIO.write(image, "jpg", out);
        }
    }

    @PostMapping("/getCode") // 发送邮箱验证码
    public Result getCode(@RequestBody @Validated Captcha captcha) {
        String uuid = captcha.getUuid();
        String code = captcha.getCode();
        // 生成图片验证码时图片验证码储存在redis中
        String code2 = String.valueOf(redisTemplate.opsForValue().get(RedisConstant.PICTURE_CODE + uuid));
        if (!StringUtils.hasLength(code2)) {
            log.error("getCode方法：图片验证码已过期");
            return Result.fail().message("图片验证码已过期");
        }
        if (!code2.equals(code)) {
            log.error("getCode方法：验证码错误");
            return Result.fail().message("验证码错误");
        }
        // 通过qq邮箱发送验证码
        captchaService.emailCode(captcha.getEmail());
        // 图片验证码使用后需要删除，避免内存浪费
        redisTemplate.delete(RedisConstant.PICTURE_CODE + uuid);
        return Result.succeed().message("验证码已发送，5分钟内有效");
    }

    @PostMapping("/check") // 校验邮箱验证码
    public Result check(@RequestParam String email, @RequestParam String code) {
        if (!StringUtils.hasLength(email) || !StringUtils.hasLength(code)) {
            log.error("check方法：邮箱或验证码为空");
            return Result.fail().message("邮箱或验证码为空");
        }
        String code2 = String.valueOf(redisTemplate.opsForValue().get(RedisConstant.EMAIL_CODE + email));
        if (!StringUtils.hasLength(code2)) {
            log.error("check方法：给定邮箱无法查询到验证码");
            return Result.fail().message("邮箱输入不一致");
        }
        if (!code.equals(code2)) {
            log.error("check方法：验证码错误");
            return Result.fail().message("验证码错误");
        }
        return Result.succeed().message("验证码正确");
    }

    @PostMapping("/register") // 注册
    public Result register(@RequestBody @Validated RegisterVO registerVO) {
        String message = userService.register(registerVO);
        if ("success".equals(message)) {
            return Result.succeed().message("注册成功");
        } else {
            log.error("register方法：" + message);
            return Result.fail().message(message);
        }
    }

    @PostMapping("/findPassword") // 找回密码
    public Result findPassword(@RequestBody @Validated FindPWVO findPWVO) {
        String message = userService.findPassword(findPWVO);
        if ("success".equals(message)) {
            return Result.succeed().message("密码修改成功");
        } else {
            log.error("findPassword方法：" + message);
            return Result.fail().message(message);
        }
    }
}
